package com.joinway.framework.admin.web.controller;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsondoc.core.annotation.Api;
import org.jsondoc.core.annotation.ApiBodyObject;
import org.jsondoc.core.annotation.ApiMethod;
import org.jsondoc.core.annotation.ApiPathParam;
import org.jsondoc.core.annotation.ApiResponseObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.joinway.framework.admin.core.bean.DataRecord;
import com.joinway.framework.admin.core.bean.view.DataGridView;
import com.joinway.framework.admin.core.bean.view.EasyUIDataGrid;
import com.joinway.framework.admin.core.service.table.TableServiceFactory;
import com.joinway.framework.admin.web.bean.form.EasyUIDeleteItemForm;
import com.joinway.framework.bean.constant.ErrorCodeConstants;
import com.joinway.framework.bean.domain.constant.SqlConstants;
import com.joinway.framework.bean.exception.InternalException;
import com.joinway.framework.bean.logging.annotation.InputLog;
import com.joinway.framework.bean.logging.annotation.LogIgnore;
import com.joinway.framework.bean.logging.annotation.OutputLog;
import com.joinway.framework.bean.security.annotation.Security;
import com.joinway.framework.bean.view.View;
import com.joinway.framework.core.controller.ExceptionController;
import com.joinway.framework.extension.groovy.DomainUtils;
import com.joinway.framework.extension.groovy.GroovyUtils;
import com.joinway.framework.extension.utils.NumberUtils;
import com.joinway.framework.support.input.annotation.Render;

@Api(name = "easyui用ajax接口", description = "")
@RestController
@RequestMapping("")
@Validated
@Security
public class EasyUIController extends ExceptionController {
	
	private final static Logger log = LoggerFactory.getLogger(EasyUIController.class);
	
	private final static String INIT_PARAM = "init";
	
	@ApiMethod(description="查找datagrid数据", produces=MediaType.APPLICATION_JSON_VALUE)
	@ApiResponseObject
	@RequestMapping(value="/search/{table}.json", produces=MediaType.APPLICATION_JSON_VALUE)
	@InputLog
//	@OutputLog
	public DataGridView searchTable(
			@PathVariable("table") @ApiPathParam(name="table", description="查询名称，通常是表名，如loginUser") @Render String table
			, @RequestParam(value="query",required=false,defaultValue="") @ApiPathParam(name="query", description="json格式的查询sql") @Render String query
			, @RequestParam(value="page",required=false,defaultValue="1") @ApiPathParam(name="page", description="查询页号，默认为1") @Render String page
			, @RequestParam(value="rows",required=false,defaultValue="30") @ApiPathParam(name="rows", description="每页数据行数，默认为30") @Render String rows
			, @LogIgnore HttpServletRequest request) throws Exception {
//		printParams(request);
		String init = null;
		if(MapUtils.isNotEmpty(request.getParameterMap())){
			String[] values = request.getParameterMap().get(INIT_PARAM);
			init = ArrayUtils.isEmpty(values) ? null : values[0];
		}
		
		String queryJson = StringUtils.isBlank(query) && StringUtils.isNotBlank(init) ? init : query;
		
		DataRecord record = TableServiceFactory.getInstance(table).find(table, queryJson, NumberUtils.convertToInt(page), NumberUtils.convertToInt(rows), request.getParameterMap());
		
		List<Map<String, ?>> records = DomainUtils.convertToRowMaps(record.getDomains());
		records = records != null ? records : new LinkedList<>();
		
		EasyUIDataGrid grid = new EasyUIDataGrid();
		grid.setTotal(record.getCount());
		grid.setRows(records);
		
		GroovyUtils.removeASTFields(grid);
		
		DataGridView view = new DataGridView();
		view.setRecord(grid);
		GroovyUtils.removeASTFields(view);
		
		return view;
	}

	@ApiMethod(description="保存数据", produces=MediaType.APPLICATION_JSON_VALUE)
	@ApiResponseObject
	@RequestMapping(value="/save/{idColumn}/{table}.json", produces=MediaType.APPLICATION_JSON_VALUE)
	@InputLog
	@OutputLog
	public View saveTable(
		@PathVariable("idColumn") @ApiPathParam(name="idColumn", description="主键列名称，如userId") @Render String idColumn
		, @PathVariable("table") @ApiPathParam(name="table", description="查询名称，通常是表名，如loginUser") @Render String table
		, @LogIgnore HttpServletRequest request
	) {
		View view = new View();
		
		try{
	//		printParams(request);
			Map<String, String> params = new HashMap<>();
			Iterator<String> keys = request.getParameterMap().keySet().iterator();
			while(keys.hasNext()){
				String k = keys.next();
				String[] v = request.getParameterMap().get(k);
				
				if(v.length == 1){
					params.put(k, StringUtils.trimToEmpty(v[0]));
				}else if(v.length > 1){
					params.put(k, StringUtils.replace(StringUtils.join(v, ","), " ", ""));
				}
			}
			
			String tableName = DomainUtils.convertToDBName(table);
			view = TableServiceFactory.getInstance(table).save(tableName, getIdColumnName(idColumn), params);
			
		}catch(Exception e){
			view.setCode(ErrorCodeConstants.SAVE_FAILURE);
			view.setMessage(ErrorCodeConstants.SAVE_FAILURE_DESC);
			view.setError(e.getMessage());
			log.error("failed to save table " + table, e);
		}
		return view;
	}
	
	@ApiMethod(description="删除数据", produces=MediaType.APPLICATION_JSON_VALUE)
	@ApiResponseObject
	@RequestMapping(value="/delete/{table}.json", produces=MediaType.APPLICATION_JSON_VALUE)
	@InputLog
	@OutputLog
	public View deleteTable(
		@PathVariable("table") @ApiPathParam(name="table", description="查询名称，通常是表名，如loginUser") @Render String table
		, @RequestBody @ApiBodyObject EasyUIDeleteItemForm form
	) throws Exception {
//		printParams(request);
		
		if(CollectionUtils.isEmpty(form.getIdValues())){
			throw new InternalException("no id was specified!");
		}
		
		if(StringUtils.isBlank(form.getSoftField())){
			TableServiceFactory.getInstance(table).delete(table, form.getIdField(), form.getIdValues());
		}else{
			TableServiceFactory.getInstance(table).delete(table, form.getIdField(), form.getIdValues(), form.getSoftField(), form.getSoftValue());
		}
		
		return new View();
	}
	
	protected String getIdColumnName(String idColumnName){
		return StringUtils.isNotBlank(idColumnName) && !"undefined".equals(idColumnName) && !"null".equals(idColumnName) ? idColumnName : SqlConstants.Key.Id;
	}
	
	private void printParams(HttpServletRequest request){
		Enumeration<String> enums = request.getParameterNames();
		while(enums.hasMoreElements()){
			String name = enums.nextElement();
			String value = request.getParameter(name);
	
			System.err.println(name + "=[" + value + "]");
//			try {
//				log.info(new String(value.getBytes("ISO-8859-1"), "UTF-8"));
//			} catch (UnsupportedEncodingException e) {
//				e.printStackTrace();
//			}
		}
	}
}


